package org.jederik.studip.android.view.tools;


import org.jederik.android.provider.StudIP;
import org.jederik.android.provider.StudIP.Feed;

import android.app.Activity;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.view.Window;

/**
 * Activities, die einzelne Resourcen darstellen sollen, können von dieser
 * Klasse abgeleitet werden.
 * @author Jann-Frederik Laß
 *
 */
public abstract class ResourceActivity extends Activity {

	private static final String TAG = "ResourceActivity";
	

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Ladesymbol in der Titelleiste anfordern:
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

		// Die Oberfläche initialisieren:
		initView();
		
	}
	
	/** Wird benachrichtigt, wenn die lokalen Daten geändert werden. */
	private final ContentObserver mContentObserver = 
		new ContentObserver(new Handler()) {

		@Override
		public void onChange(boolean selfChange) {
			loadContent();
		}
		
	};
	
	@Override
	protected void onResume() {
		super.onResume();

		// Für Benachrichtigungen über Änderungen der Daten registrieren:
		getContentResolver().registerContentObserver(
				getIntent().getData(), 
				false, 
				mContentObserver
		);

		// Aktuellen Inhalt zeigen:
		loadContent();
		
	}

	@Override
	protected void onPause() {
		super.onPause();
		
		// ContentObserver entfernen:
		getContentResolver().unregisterContentObserver(mContentObserver);

	}

	protected void setVisited() {

		new AsyncTask<Object, Object, Object>() {

			@Override
			protected Object doInBackground(Object... data) {
				
				Uri objectUri = Uri.withAppendedPath(Feed.CONTENT_URI, getId());
				
				// Resource in lokaler Datenbank als gelesen und zur
				// Synchronisation ausstehend markieren:
				ContentValues values = new ContentValues();
				values.put(Feed.READ, "1");
				values.put(StudIP._SYNC_STATE, StudIP.STATE_PENDING);
				getContentResolver().update(objectUri, values, null, null);
				
				return null;
			}
			
		}.execute((Object) null);
	}

	/**
	 * Lädt die Oberfläche der Activity. Dies ist nötig, damit das Ladesymbol
	 * angezeigt werden kann.
	 */
	public abstract void initView();

	/** Lädt den Inhalt in einem extra Thread */
	private class Loader extends AsyncTask<Object, Object, Cursor> {

		@Override
		protected Cursor doInBackground(Object... params) {
			
			// Inhalt von Content Provider laden:
			return managedQuery(getIntent().getData(), null, null, null, null);

		}

		@Override
		protected void onPostExecute(Cursor resource) {

			// Resource anzeigen:
			displayResource(resource);

		}
	};
	
	public void displayResource(Cursor resource) {

		if (
				resource == null || 
				resource.isClosed() || 
				!resource.moveToFirst()
		) return;

		// Synchronisationsstatus der Resource auslesen:
		int syncState = 
			resource.getInt(resource.getColumnIndex(StudIP._SYNC_STATE));

		// Synchronisationsstatus auslesen:
		switch(syncState) {

		case StudIP.STATE_SYNCHRONIZED:

			// Als gelesen markieren:
			if (canBeVisited()) {
				setVisited();
			}

		case StudIP.STATE_PENDING:
		case StudIP.STATE_FAILED:

			// Kein Ladesymbol einblenden:
			setProgressBarIndeterminateVisibility(false);

			// Und Inhalt anzeigen:
			break;

		case StudIP.STATE_SYNCHRONIZING:

			// Falls Status SYNCHRONIZING,
			// Ladesymbol einblenden:
			setProgressBarIndeterminateVisibility(true);

		}


		// Inhalt anzeigen:
		showData(resource);

	}

	public void loadContent() {
		
		// Der Zugriff auf den ContentResolver findet in einem extra Thread statt:
		new Loader().execute(getIntent().getData());
	}
	
	/** Gibt die Stud-IP-ID der Resource zurück */
	public abstract String getId();
	
	/** Gibt an, ob die Resource als gelesen markiert werden kann */
	public abstract boolean canBeVisited();
	
	/** Zeigt die in einem Cursor enthaltenen Daten auf der Oberfläche an */
	public abstract void showData(Cursor content);
	
	/** Liefert den Resourcentyp ({@code news}, {@code message}, {@code schedule}, ...) */
	public abstract String getType();

}
